/**
 * 华为云IoT设备数据服务
 * 用于获取设备消息和状态信息
 */

import type { 
  AuthRequest, 
  TokenResponse, 
  DeviceListResponse, 
  DeviceShadowResponse, 
  DeviceMessageRequest,
  DeviceMessageResponse,
  Device,
  Shadow
} from './huaweiCloudTypes';

export interface IoTMessage {
  id: string;
  type: 'info' | 'warning' | 'success' | 'error';
  content: string;
  time: string;
  deviceId?: string;
  deviceName?: string;
  source: 'device' | 'system';
}

export class HuaweiCloudIoTService {
  private static token: string | null = null;
  private static tokenExpireTime: number = 0;
  private static readonly PROJECT_ID = '4e458aaaa92f41d686b5cb6e193d4e34'; // 更新为正确的项目ID
  
  // 设备状态缓存，用于检测变化
  private static deviceStatesCache: Map<string, Record<string, any>> = new Map();
  
  // 请求节流控制
  private static lastRequestTime: number = 0;
  private static readonly MIN_REQUEST_INTERVAL = 500; // 最小请求间隔500ms
  
  // 错误计数和重试控制
  private static errorCount: number = 0;
  private static readonly MAX_ERRORS = 5;
  private static nextRetryTime: number = 0;
  
  /**
   * 清空设备状态缓存（用于测试和强制刷新）
   */
  static clearDeviceCache(): void {
    console.log('🗑️ 清空设备状态缓存');
    this.deviceStatesCache.clear();
  }
  
  /**
   * 获取当前缓存状态（用于调试）
   */
  static getDeviceCacheStatus(): Record<string, any> {
    const cacheStatus: Record<string, any> = {};
    this.deviceStatesCache.forEach((value, key) => {
      cacheStatus[key] = value;
    });
    return cacheStatus;
  }
  
  /**
   * 检查是否可以发送请求（节流控制）
   */
  private static canMakeRequest(): boolean {
    const now = Date.now();
    
    // 检查错误重试时间
    if (now < this.nextRetryTime) {
      console.log(`⏳ 等待重试，剩余时间: ${Math.ceil((this.nextRetryTime - now) / 1000)}秒`);
      return false;
    }
    
    // 检查请求间隔
    if (now - this.lastRequestTime < this.MIN_REQUEST_INTERVAL) {
      console.log('⏱️ 请求过于频繁，跳过此次请求');
      return false;
    }
    
    return true;
  }
  
  /**
   * 记录请求成功
   */
  private static recordSuccess(): void {
    this.lastRequestTime = Date.now();
    this.errorCount = 0;
    this.nextRetryTime = 0;
  }
  
  /**
   * 记录请求失败
   */
  private static recordError(): void {
    this.errorCount++;
    this.lastRequestTime = Date.now();
    
    if (this.errorCount >= this.MAX_ERRORS) {
      // 错误次数过多，延长重试时间
      this.nextRetryTime = Date.now() + (this.errorCount - this.MAX_ERRORS + 1) * 10000; // 10秒 * 错误次数
      console.warn(`❌ 连续错误${this.errorCount}次，延迟${(this.nextRetryTime - Date.now()) / 1000}秒后重试`);
    }
  }
  
  // API地址 - 使用代理路径避免CORS问题
  private static readonly IAM_URL = '/huawei-iam';
  private static readonly IOT_URL = '/huawei-iot';

  /**
   * 获取访问令牌
   */
  private static async getToken(): Promise<string> {
    const now = Date.now();
    
    // 如果token还有效，直接返回
    if (this.token && now < this.tokenExpireTime) {
      return this.token;
    }

    try {
      console.log('🔐 正在获取华为云访问令牌...');
      
      const authRequest: AuthRequest = {
        auth: {
          identity: {
            methods: ['password'],
            password: {
              user: {
                name: 'root',
                password: 'Sytail2025',
                domain: {
                  name: 'sytail'
                }
              }
            }
          },
          scope: {
            project: {
              name: 'cn-south-1'
            }
          }
        }
      };

      const response = await fetch(`${this.IAM_URL}/v3/auth/tokens`, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify(authRequest)
      });

      if (!response.ok) {
        throw new Error(`获取Token失败: ${response.status} ${response.statusText}`);
      }

      // 从响应头获取token
      const token = response.headers.get('x-subject-token');
      if (!token) {
        throw new Error('响应头中未找到x-subject-token');
      }

      // 获取token过期时间
      const tokenData: TokenResponse = await response.json();
      const expiresAt = new Date(tokenData.token.expires_at).getTime();
      
      this.token = token;
      this.tokenExpireTime = expiresAt - 5 * 60 * 1000; // 提前5分钟刷新
      
      console.log('✅ 成功获取华为云访问令牌');
      return token;
    } catch (error) {
      console.error('❌ 获取华为云访问令牌失败:', error);
      throw error;
    }
  }

  /**
   * 发送带认证的请求
   */
  private static async authenticatedRequest<T>(url: string, options: RequestInit = {}): Promise<T> {
    const token = await this.getToken();
    
    const response = await fetch(url, {
      ...options,
      headers: {
        'Content-Type': 'application/json',
        'X-Auth-Token': token,
        ...options.headers,
      },
    });

    if (!response.ok) {
      throw new Error(`请求失败: ${response.status} ${response.statusText}`);
    }

    return response.json();
  }

  /**
   * 获取设备列表
   */
  static async getDevicesList(): Promise<Device[]> {
    try {
      console.log('📱 正在获取设备列表...');
      
      const data = await this.authenticatedRequest<DeviceListResponse>(
        `${this.IOT_URL}/v5/iot/${this.PROJECT_ID}/devices`
      );
      
      console.log(`✅ 成功获取 ${data.devices.length} 个设备`);
      return data.devices;
    } catch (error) {
      console.error('❌ 获取设备列表失败:', error);
      return [];
    }
  }

  /**
   * 获取设备影子数据
   */
  static async getDeviceShadow(deviceId: string): Promise<Shadow[]> {
    try {
      console.log(`🔍 正在获取设备 ${deviceId} 的影子数据...`);
      
      const data = await this.authenticatedRequest<DeviceShadowResponse>(
        `${this.IOT_URL}/v5/iot/${this.PROJECT_ID}/devices/${deviceId}/shadow`
      );
      
      console.log(`✅ 成功获取设备影子数据`);
      return data.shadow;
    } catch (error) {
      console.error(`❌ 获取设备影子数据失败:`, error);
      return [];
    }
  }

  /**
   * 发送设备消息
   */
  static async sendDeviceMessage(deviceId: string, message: DeviceMessageRequest): Promise<DeviceMessageResponse | null> {
    try {
      console.log(`📤 正在向设备 ${deviceId} 发送消息...`);
      
      const data = await this.authenticatedRequest<DeviceMessageResponse>(
        `${this.IOT_URL}/v5/iot/${this.PROJECT_ID}/devices/${deviceId}/messages`,
        {
          method: 'POST',
          body: JSON.stringify(message)
        }
      );
      
      console.log(`✅ 成功发送设备消息`);
      return data;
    } catch (error) {
      console.error(`❌ 发送设备消息失败:`, error);
      return null;
    }
  }

  /**
   * 清理和标准化设备属性（处理乱码和冗余数据）
   */
  private static cleanDeviceProperties(properties: Record<string, any>): Record<string, any> {
    const cleanedProperties: Record<string, any> = {};
    
    // 定义需要的属性和它们的清理规则
    const targetProperties = {
      'fan_flag': ['fan_flag'],
      'airconditioner_flag': ['airconditioner_flag'], 
      'heating_flag': ['heating_flag'],
      'lamplight_flag': ['lamplight_flag'],
      'mode_flag': ['mode_flag'],
      'alarm': ['alarm']
    };
    
    // 清理每个目标属性
    for (const [targetKey, possibleKeys] of Object.entries(targetProperties)) {
      // 查找第一个有效的属性值
      for (const key of possibleKeys) {
        if (properties[key] !== undefined && properties[key] !== null) {
          const value = properties[key];
          // 跳过明显错误的值（如包含乱码的key或无意义的值）
          if (typeof value === 'string' && key === targetKey) {
            cleanedProperties[targetKey] = value;
            break;
          } else if (typeof value === 'number' && key === targetKey) {
            // 数字类型转换为标准格式
            cleanedProperties[targetKey] = value === 1 ? 'ON' : 'OFF';
            break;
          }
        }
      }
      
      // 如果没找到有效值，设置默认值
      if (cleanedProperties[targetKey] === undefined) {
        cleanedProperties[targetKey] = 'OFF';
      }
    }
    
    console.log('🧹 设备属性清理结果:', {
      原始属性数量: Object.keys(properties).length,
      清理后属性: cleanedProperties
    });
    
    return cleanedProperties;
  }
  /**
   * 检测设备状态变化并生成相应消息
   */
  private static detectDeviceChanges(deviceId: string, deviceName: string, rawProperties: Record<string, any>): IoTMessage[] {
    const messages: IoTMessage[] = [];
    
    // 首先清理设备属性
    const currentProperties = this.cleanDeviceProperties(rawProperties);
    const previousProperties = this.deviceStatesCache.get(deviceId) || {};
    
    console.log(`🔍 检测设备 ${deviceName} 状态变化:`);
    console.log(`   - 当前属性:`, currentProperties);
    console.log(`   - 缓存属性:`, previousProperties);
    
    // 定义需要监控的设备属性
    const monitoredProperties = {
      'fan_flag': '风扇设备',
      'airconditioner_flag': '空调设备', 
      'heating_flag': '暖气设备',
      'lamplight_flag': '灯光设备',
      'mode_flag': '设备模式',
      'alarm': '报警状态'
    };
    
    // 检查每个监控属性的变化
    for (const [propKey, propName] of Object.entries(monitoredProperties)) {
      const currentValue = currentProperties[propKey];
      const previousValue = previousProperties[propKey];
      
      console.log(`   - 检查 ${propName} (${propKey}): ${previousValue} -> ${currentValue}`);
      
      // 如果值发生了变化（包括从undefined到有值）
      if (currentValue !== undefined && currentValue !== previousValue) {
        let messageType: IoTMessage['type'] = 'info';
        let content = '';
        
        // 标准化值（支持多种格式）
        const isCurrentOn = this.normalizeStateValue(currentValue);
        const wasPreviousOn = this.normalizeStateValue(previousValue);
        
        console.log(`     - 标准化值: ${wasPreviousOn} -> ${isCurrentOn}`);
        
        // 只有在真正的状态切换时才生成消息
        if (isCurrentOn !== wasPreviousOn || previousValue === undefined) {
          if (propKey === 'alarm') {
            // 报警状态特殊处理
            if (isCurrentOn) {
              messageType = 'error';
              content = `⚠️ ${deviceName} 触发报警！`;
            } else {
              messageType = 'success';
              content = `✅ ${deviceName} 报警状态已解除`;
            }
          } else if (propKey === 'mode_flag') {
            // 模式变化特殊处理
            messageType = 'info';
            content = `🔄 用户${isCurrentOn ? '启用' : '禁用'}了${deviceName}的${propName}`;
          } else {
            // 普通设备状态变化
            if (isCurrentOn) {
              messageType = 'success';
              content = `✨ 用户开启了${deviceName}的${propName}`;
            } else {
              messageType = 'info';
              content = `🔌 用户关闭了${deviceName}的${propName}`;
            }
          }
          
          const changeMessage = {
            id: `${deviceId}_${propKey}_change_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
            type: messageType,
            content,
            time: new Date().toLocaleTimeString('zh-CN', { 
              hour: '2-digit', 
              minute: '2-digit' 
            }),
            deviceId,
            deviceName,
            source: 'device' as const
          };
          
          messages.push(changeMessage);
          
          console.log(`🎯 生成状态变化消息: ${content}`);
        }
      }
    }
    
    // 更新缓存（使用清理后的属性）
    this.deviceStatesCache.set(deviceId, { ...currentProperties });
    console.log(`💾 更新设备 ${deviceName} 缓存状态`);
    
    return messages;
  }
  
  /**
   * 标准化状态值（支持多种格式：ON/OFF, 1/0, true/false等）
   */
  private static normalizeStateValue(value: any): boolean {
    if (value === undefined || value === null) return false;
    
    const strValue = String(value).toUpperCase();
    return strValue === 'ON' || strValue === '1' || strValue === 'TRUE' || value === 1 || value === true;
  }

  /**
   * 获取设备实时消息（基于设备状态和影子数据生成）
   */
  static async getDeviceMessages(): Promise<IoTMessage[]> {
    // 首先检查是否可以发送请求
    if (!this.canMakeRequest()) {
      console.log('🚫 跳过此次华为云IoT请求（节流控制）');
      
      // 返回缓存的状态信息，避免显示重复消息
      return this.generateCachedStatusMessages();
    }
    
    try {
      console.log('🔍 开始获取华为云IoT设备消息...');
      const devices = await this.getDevicesList();
      console.log(`📱 获取到 ${devices.length} 个设备`);
      
      const messages: IoTMessage[] = [];
      
      // 最多处理前3个设备，优先查找状态变化
      const devicesToProcess = devices.slice(0, 3);
      
      for (const device of devicesToProcess) {
        try {
          console.log(`🔍 正在检查设备 ${device.device_name} (${device.device_id})`);
          
          // 检查设备在线状态
          if (device.status === 'OFFLINE') {
            console.log(`🔴 设备 ${device.device_name} 离线`);
            const offlineMessage = {
              id: `${device.device_id}_offline_${Date.now()}_${Math.random().toString(36).substr(2, 5)}`,
              type: 'error' as const,
              content: `🔴 设备 ${device.device_name} 离线`,
              time: new Date().toLocaleTimeString('zh-CN', { 
                hour: '2-digit', 
                minute: '2-digit',
                second: '2-digit'
              }),
              deviceId: device.device_id,
              deviceName: device.device_name,
              source: 'device' as const
            };
            messages.push(offlineMessage);
            continue;
          }
          
          const shadows = await this.getDeviceShadow(device.device_id);
          
          // 基于设备状态生成消息
          if (device.status === 'ONLINE') {
            console.log(`✅ 设备 ${device.device_name} 在线`);
            
            // 分析设备影子数据，检测状态变化
            if (shadows && shadows.length > 0) {
              const shadow = shadows[0];
              const properties = shadow.reported?.properties || shadow.desired?.properties || {};
              
              console.log(`📊 设备 ${device.device_name} 当前属性:`, properties);
              
              // 检测设备状态变化并生成相应消息
              const changeMessages = this.detectDeviceChanges(device.device_id, device.device_name, properties);
              console.log(`🔄 设备 ${device.device_name} 状态变化消息数量: ${changeMessages.length}`);
              
              if (changeMessages.length > 0) {
                messages.push(...changeMessages);
                console.log(`🎯 添加了 ${changeMessages.length} 条状态变化消息`);
              }
              
              // 如果没有状态变化但需要填充消息，生成当前状态信息
              if (changeMessages.length === 0 && messages.length < 2) {
                const statusMessage = this.getImportantDeviceStatus(properties, device.device_name);
                if (statusMessage && !this.isDuplicateMessage(statusMessage, messages)) {
                  console.log(`📌 添加状态消息: ${statusMessage.content}`);
                  messages.push(statusMessage);
                }
              }
            } else {
              // 没有影子数据时的默认消息
              if (messages.length < 2) {
                const onlineMessage = {
                  id: `${device.device_id}_online_${Date.now()}_${Math.random().toString(36).substr(2, 5)}`,
                  type: 'success' as const,
                  content: `📱 设备 ${device.device_name} 在线运行中`,
                  time: new Date().toLocaleTimeString('zh-CN', { 
                    hour: '2-digit', 
                    minute: '2-digit',
                    second: '2-digit'
                  }),
                  deviceId: device.device_id,
                  deviceName: device.device_name,
                  source: 'device' as const
                };
                if (!this.isDuplicateMessage(onlineMessage, messages)) {
                  console.log(`🟢 添加在线消息: ${onlineMessage.content}`);
                  messages.push(onlineMessage);
                }
              }
            }
          }
          
          if (messages.length >= 2) {
            console.log('📝 已获取足够消息，停止处理更多设备');
            break; // 最多2条消息
          }
        } catch (error) {
          console.warn(`⚠️ 获取设备 ${device.device_id} 数据失败:`, error);
        }
      }
      
      // 确保消息的唯一性和时效性
      const uniqueMessages = this.deduplicateMessages(messages);
      
      // 如果没有获取到设备消息，生成默认的系统消息
      if (uniqueMessages.length === 0) {
        console.log('📝 没有设备消息，生成默认系统消息');
        uniqueMessages.push(...this.generateDefaultSystemMessages());
      } else if (uniqueMessages.length === 1) {
        // 如果只有1条消息，补充一条系统消息
        console.log('📝 只有1条消息，补充系统消息');
        const systemMessage = this.generateSystemMessage();
        if (systemMessage && !this.isDuplicateMessage(systemMessage, uniqueMessages)) {
          uniqueMessages.push(systemMessage);
        }
      }
      
      console.log(`✅ 最终生成了 ${uniqueMessages.length} 条设备消息`);
      console.log('📋 消息列表:', uniqueMessages.map(m => ({ 
        id: m.id, 
        type: m.type, 
        content: m.content,
        time: m.time
      })));
      
      // 记录请求成功
      this.recordSuccess();
      
      return uniqueMessages.slice(0, 2); // 确保只返回2条消息
      
    } catch (error) {
      console.error('❌ 获取设备消息失败:', error);
      
      // 记录请求失败
      this.recordError();
      
      // 返回默认消息
      return this.generateFallbackMessages();
    }
  }
  
  /**
   * 获取设备的重要状态信息（当没有状态变化时显示）
   */
  private static getImportantDeviceStatus(rawProperties: Record<string, any>, deviceName: string): IoTMessage | null {
    // 清理设备属性
    const properties = this.cleanDeviceProperties(rawProperties);
    
    // 检查报警状态
    if (this.normalizeStateValue(properties.alarm)) {
      return {
        id: `status_alarm_${Date.now()}_${Math.random().toString(36).substr(2, 5)}`,
        type: 'error',
        content: `⚠️ ${deviceName} 报警状态激活`,
        time: new Date().toLocaleTimeString('zh-CN', { 
          hour: '2-digit', 
          minute: '2-digit',
          second: '2-digit'
        }),
        deviceName,
        source: 'device'
      };
    }
    
    // 检查运行中的设备
    const runningDevices = [];
    if (this.normalizeStateValue(properties.fan_flag)) runningDevices.push('风扇');
    if (this.normalizeStateValue(properties.airconditioner_flag)) runningDevices.push('空调');
    if (this.normalizeStateValue(properties.heating_flag)) runningDevices.push('暖气');
    if (this.normalizeStateValue(properties.lamplight_flag)) runningDevices.push('灯光');
    
    if (runningDevices.length > 0) {
      return {
        id: `status_running_${Date.now()}_${Math.random().toString(36).substr(2, 5)}`,
        type: 'success',
        content: `🟢 ${deviceName} ${runningDevices.join('、')}设备正在运行`,
        time: new Date().toLocaleTimeString('zh-CN', { 
          hour: '2-digit', 
          minute: '2-digit',
          second: '2-digit'
        }),
        deviceName,
        source: 'device'
      };
    }
    
    // 所有设备都关闭
    return {
      id: `status_idle_${Date.now()}_${Math.random().toString(36).substr(2, 5)}`,
      type: 'info',
      content: `💤 ${deviceName} 所有设备处于关闭状态`,
      time: new Date().toLocaleTimeString('zh-CN', { 
        hour: '2-digit', 
        minute: '2-digit',
        second: '2-digit'
      }),
      deviceName,
      source: 'device'
    };
  }

  /**
   * 检查消息是否重复
   */
  private static isDuplicateMessage(newMessage: IoTMessage, existingMessages: IoTMessage[]): boolean {
    return existingMessages.some(msg => 
      msg.content === newMessage.content && 
      msg.type === newMessage.type &&
      msg.deviceName === newMessage.deviceName
    );
  }

  /**
   * 去重消息列表
   */
  private static deduplicateMessages(messages: IoTMessage[]): IoTMessage[] {
    const seen = new Set<string>();
    return messages.filter(msg => {
      const key = `${msg.content}_${msg.type}_${msg.deviceName || 'system'}`;
      if (seen.has(key)) {
        return false;
      }
      seen.add(key);
      return true;
    });
  }

  /**
   * 生成缓存状态消息（节流时使用）
   */
  private static generateCachedStatusMessages(): IoTMessage[] {
    const now = new Date();
    return [
      {
        id: `cached_status_${now.getTime()}`,
        type: 'info',
        content: '🔄 设备状态监控中...',
        time: now.toLocaleTimeString('zh-CN', { 
          hour: '2-digit', 
          minute: '2-digit',
          second: '2-digit'
        }),
        source: 'system'
      },
      {
        id: `cached_monitor_${now.getTime() + 1}`,
        type: 'success',
        content: '📡 实时数据更新中',
        time: now.toLocaleTimeString('zh-CN', { 
          hour: '2-digit', 
          minute: '2-digit',
          second: '2-digit'
        }),
        source: 'system'
      }
    ];
  }

  /**
   * 生成默认系统消息
   */
  private static generateDefaultSystemMessages(): IoTMessage[] {
    const now = new Date();
    return [
      {
        id: `system_info_${now.getTime()}`,
        type: 'info',
        content: '🏫 智慧校园系统运行正常',
        time: now.toLocaleTimeString('zh-CN', { 
          hour: '2-digit', 
          minute: '2-digit',
          second: '2-digit'
        }),
        source: 'system'
      },
      {
        id: `system_monitoring_${now.getTime() + 1}`,
        type: 'success',
        content: '🔍 设备监控系统已启动',
        time: now.toLocaleTimeString('zh-CN', { 
          hour: '2-digit', 
          minute: '2-digit',
          second: '2-digit'
        }),
        source: 'system'
      }
    ];
  }

  /**
   * 生成单个系统消息
   */
  private static generateSystemMessage(): IoTMessage {
    const messages = [
      '📊 环境监测数据更新完成',
      '🔋 设备电量状态良好',
      '🌡️ 温度传感器正常工作',
      '💧 湿度监测系统运行中',
      '🔍 系统自检完成',
      '📱 设备连接状态稳定'
    ];
    
    const content = messages[Math.floor(Math.random() * messages.length)];
    const now = new Date();
    
    return {
      id: `system_${now.getTime()}_${Math.random().toString(36).substr(2, 5)}`,
      type: 'info',
      content,
      time: now.toLocaleTimeString('zh-CN', { 
        hour: '2-digit', 
        minute: '2-digit',
        second: '2-digit'
      }),
      source: 'system'
    };
  }

  /**
   * 生成失败时的后备消息
   */
  private static generateFallbackMessages(): IoTMessage[] {
    const now = new Date();
    return [
      {
        id: `fallback_1_${now.getTime()}`,
        type: 'warning',
        content: '⚠️ 设备连接中断，正在重新连接...',
        time: now.toLocaleTimeString('zh-CN', { 
          hour: '2-digit', 
          minute: '2-digit',
          second: '2-digit'
        }),
        source: 'system'
      },
      {
        id: `fallback_2_${now.getTime() + 1}`,
        type: 'info',
        content: '🔄 系统自检完成，运行状态良好',
        time: now.toLocaleTimeString('zh-CN', { 
          hour: '2-digit', 
          minute: '2-digit',
          second: '2-digit'
        }),
        source: 'system'
      }
    ];
  }
}
